#include "terminal.h"


#ifdef __cplusplus
 extern "C" {
#endif /* __cplusplus */

extern typeTime pTimer;

CtrlPeriph CtrlPeriph_Var[] = {
	{"ver", Terminal_Command_Ver, "Version"},
	{"help", Terminal_Command_Help, "Help"},
	{"led", Terminal_Peripheral_Led, "Control the all led"},
	{"led3", Terminal_Peripheral_Led, "Control the led 3"},
	{"led4", Terminal_Peripheral_Led, "Control the led 4"},
	{"led5", Terminal_Peripheral_Led, "Control the led 5"},
	{"led6", Terminal_Peripheral_Led, "Control the led 6"},
	{"setsec", Terminal_Time_Sec, "Set Second"},
	{"setmin", Terminal_Time_Min, "Set Minutes"},
	{"sethour", Terminal_Time_Hour, "Set Hour"},
	{"setday", Terminal_Time_Day, "Set Day of week"},
	{"setdate", Terminal_Time_Date, "Set Day of month"},
	{"setmonth", Terminal_Time_Month, "Set Month"},
	{"setyear", Terminal_Time_Year, "Set Year"},
	{"settime", Terminal_Set_Time, "Set Time"},
	{NULL, NULL, NULL}
};


/***************************************************************************************
 *	Terminal_Init
 *
 ***************************************************************************************/
uint8_t Terminal_Init(void)
{
	GPIO_InitTypeDef	Ctrl_GPIO;
	USART_InitTypeDef	Ctrl_UART;
	NVIC_InitTypeDef	Interrupt_USART;

	/* Enable GPIO clock */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	/* Enable UART clock */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	/* Configure USART Tx as alternate function  */
	Ctrl_GPIO.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
	Ctrl_GPIO.GPIO_OType = GPIO_OType_PP;
	Ctrl_GPIO.GPIO_PuPd = GPIO_PuPd_UP;
	Ctrl_GPIO.GPIO_Mode = GPIO_Mode_AF;
	Ctrl_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
	Ctrl_GPIO.GPIO_Mode = GPIO_Mode_AF;
	GPIO_Init(PORT_GPIO_USART, &Ctrl_GPIO);

	/* Connect PXx to USARTx_Tx*/
	GPIO_PinAFConfig(PORT_GPIO_USART, GPIO_PinSource_TX, GPIO_AF_TX);

	/* Connect PXx to USARTx_Rx*/
	GPIO_PinAFConfig(PORT_GPIO_USART, GPIO_PinSource_RX, GPIO_AF_RX);

	// install GPIO for PORT_USART: Pin A2, Pin A3
	Ctrl_UART.USART_BaudRate = 115200;
	Ctrl_UART.USART_WordLength = USART_WordLength_8b;
	Ctrl_UART.USART_StopBits = USART_StopBits_1;
	Ctrl_UART.USART_Parity = USART_Parity_No;
	Ctrl_UART.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	Ctrl_UART.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

	/* USART configuration */
	USART_Init(PORT_USART, &Ctrl_UART);

	/*
	 * Init interrupt for USART
	 */
	USART_ITConfig(PORT_USART, USART_IT_RXNE, ENABLE);
        
	Interrupt_USART.NVIC_IRQChannel = USART2_IRQn;
	Interrupt_USART.NVIC_IRQChannelPreemptionPriority = 0;
	Interrupt_USART.NVIC_IRQChannelSubPriority = 1;
	Interrupt_USART.NVIC_IRQChannelCmd = ENABLE;

	NVIC_Init(&Interrupt_USART);
	NVIC_EnableIRQ(USART2_IRQn);

	/* Enable USART */
	USART_Cmd(PORT_USART, ENABLE);
        
	return 0;
}



/***************************************************************************************
 *	Send_Char
 *
 ***************************************************************************************/
void Send_Char(uint8_t u8_Char)
{
	USART_SendData(PORT_USART, (uint8_t) u8_Char);
	while (USART_GetFlagStatus(PORT_USART, USART_FLAG_TC) == RESET);
}


/***************************************************************************************
 *	Send_String
 *
 ***************************************************************************************/
void Send_String(uint8_t *pString)
{
	while(*pString)
	{
		Send_Char(*pString);
		pString++;
	}
}


/***************************************************************************************
 *	Receive_Char
 *
 ***************************************************************************************/
uint8_t Receive_Char(void)
{
	uint16_t u16_Char;
	while(USART_GetFlagStatus(PORT_USART,USART_FLAG_RXNE) == RESET);
	u16_Char = USART_ReceiveData(PORT_USART);
	return ((uint8_t)u16_Char);
}


/***************************************************************************************
 *	Phan_Tach
 *
 ***************************************************************************************/
void Terminal_Command_Data(uint8_t *pu8_InBuffer, uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	uint8_t	u8_Local = 0;
	uint8_t u8_Object = 0;

	pu8_Command[0] = '\0';
	pu8_Data[0] = '\0';

	while(*pu8_InBuffer)
	{
		if ((*pu8_InBuffer == ' ')&&(0 == u8_Object))
		{
			u8_Local = 0;
			u8_Object++;
		}
		else
		{
			if (u8_Object == 0)
			{
				pu8_Command[u8_Local++] = *pu8_InBuffer;
				pu8_Command[u8_Local] = '\0';
			}			
			else /* (u8_Object != 0) */
			{
				pu8_Data[u8_Local++] = *pu8_InBuffer;
				pu8_Data[u8_Local] = '\0';
			}
		}
		pu8_InBuffer++;
	}
}


/***************************************************************************************
 *	Terminal_Print_Help
 *
 ***************************************************************************************/
void Terminal_Print_Help(uint8_t *pu8_Command, uint8_t *pu8_Comment)
{
	Send_String("\n");
	Send_String(pu8_Command);
	Send_String("\t:\t");
	Send_String(pu8_Comment);
}


/***************************************************************************************
 *	Terminal_Command_Ver
 *
 ***************************************************************************************/
uint8_t Terminal_Command_Ver(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	Send_String("\nVersion v1.0");
	Send_String("\nEmail: votuananhs@gmail.com");
	return 0;
}


/***************************************************************************************
 * 	Terminal_Command_Help
 *
 ***************************************************************************************/
uint8_t Terminal_Command_Help(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	uint8_t i = 0;

	Send_String("\nList commands support on Terminal:");
	while(1)
	{
		if (CtrlPeriph_Var[i].pu8_Command == NULL) break;
		Terminal_Print_Help(CtrlPeriph_Var[i].pu8_Command, CtrlPeriph_Var[i].pu8_Comment);
		i++;
	}
	return 0;
}


/***************************************************************************************
 *	Terminal_Peripheral_Led
 *
 ***************************************************************************************/
uint8_t Terminal_Peripheral_Led(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data,"on") == 0)
	{
		if (strcmp(pu8_Command, "led") == 0)
		{
			STM_EVAL_LEDOn(LED3);
			STM_EVAL_LEDOn(LED4);
			STM_EVAL_LEDOn(LED5);
			STM_EVAL_LEDOn(LED6);
			Send_String("\nCompleted 'on all led' !");
		}
		else if (strcmp(pu8_Command, "led3") == 0)
		{
			STM_EVAL_LEDOn(LED3);
			Send_String("\nCompleted 'on led3' !");
		}
		else if (strcmp(pu8_Command, "led4") == 0)
		{
			STM_EVAL_LEDOn(LED4);
			Send_String("\nCompleted 'on led4' !");
		}
		else if (strcmp(pu8_Command, "led5") == 0)
		{
			STM_EVAL_LEDOn(LED5);
			Send_String("\nCompleted 'on led5' !");
		}
		else if (strcmp(pu8_Command, "led6") == 0)
		{
			STM_EVAL_LEDOn(LED6);
			Send_String("\nCompleted 'on led6' !");
		}
		else
		{
			Send_String("\nNot exist this command !\n");
		}
	}
	else if (strcmp(pu8_Data, "off") == 0)
	{
		if (strcmp(pu8_Command, "led") == 0)
		{
			STM_EVAL_LEDOff(LED3);
			STM_EVAL_LEDOff(LED4);
			STM_EVAL_LEDOff(LED5);
			STM_EVAL_LEDOff(LED6);
			Send_String("\nCompleted 'off all led' !");
		}
		else if (strcmp(pu8_Command, "led3") == 0)
		{
			STM_EVAL_LEDOff(LED3);
			Send_String("\nCompleted 'off led3' !");
		}
		else if (strcmp(pu8_Command, "led4") == 0)
		{
			STM_EVAL_LEDOff(LED4);
			Send_String("\nCompleted 'off led4' !");
		}
		else if (strcmp(pu8_Command, "led5") == 0)
		{
			STM_EVAL_LEDOff(LED5);
			Send_String("\nCompleted 'off led5' !");
		}
		else if (strcmp(pu8_Command, "led6") == 0)
		{
			STM_EVAL_LEDOff(LED6);
			Send_String("\nCompleted 'off led6' !");
		}
		else
		{
			Send_String("\nNot exist this command !\n");
		}
	}
	else if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\n\tThere are two commands the controller leds:");
		Send_String("\n\t\tbat \t'on' for turn on led");
		Send_String("\n\t\ttat \t'off' for turn off led");
	}
	else
	{
		Send_String("\nNot exist this command !\n");
	}
	return 0;
}

uint8_t Terminal_Time_Sec(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Second the DS1307 IC !");
	}
	else
	{
		Send_String("\nSecond =\t");
		Send_String(pu8_Data);
		pTimer.Sec = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Min(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Minutes the DS1307 IC !");
	}
	else
	{
		Send_String("\nMinute =\t");
		Send_String(pu8_Data);
		pTimer.Min = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Hour(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Hours the DS1307 IC !");
	}
	else
	{
		Send_String("\nHour =\t");
		Send_String(pu8_Data);
		pTimer.Hour = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Day(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Day the DS1307 IC !");
	}
	else
	{
		Send_String("\nDay =\t");
		Send_String(pu8_Data);
		pTimer.Day = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Date(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Date the DS1307 IC !");
	}
	else
	{
		Send_String("\nDate =\t");
		Send_String(pu8_Data);
		pTimer.Date = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Month(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Month the DS1307 IC !");
	}
	else
	{
		Send_String("\nMonth =\t");
		Send_String(pu8_Data);
		pTimer.Month = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}

uint8_t Terminal_Time_Year(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Year the DS1307 IC !");
	}
	else
	{
		Send_String("\nYear =\t");
		Send_String(pu8_Data);
		pTimer.Year = (uint8_t)atoi(pu8_Data);
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}


uint8_t Terminal_Set_Time(uint8_t *pu8_Command, uint8_t *pu8_Data)
{
	uint8_t *au8_temp;
	uint8_t i=0;
	if (strcmp(pu8_Data, "help") == 0)
	{
		Send_String("\nSetting of Year the DS1307 IC !");
		Send_String("\nH/M/S\tDW\tD/M/Y");

	}
	else
	{
		Send_String("\nTime =\t");
		Send_String(pu8_Data);
		au8_temp = strtok(pu8_Data, " :/");
		while (au8_temp != NULL)
		{
			switch(i)
			{
				case 0: pTimer.Hour = (uint8_t)atoi(au8_temp); break;
				case 1:	pTimer.Min = (uint8_t)atoi(au8_temp); break;
				case 2:	pTimer.Sec = (uint8_t)atoi(au8_temp); break;
				case 3:	pTimer.Day = (uint8_t)atoi(au8_temp); break; /* CN = 1 -> T7 = 7*/
				case 4:	pTimer.Date = (uint8_t)atoi(au8_temp); break;
				case 5:	pTimer.Month = (uint8_t)atoi(au8_temp); break;
				case 6:	pTimer.Year = (uint8_t)atoi(au8_temp); break;
				default :  break;
			};
			au8_temp = strtok(NULL, " :/");
			i++;
		}
		WriteTime_DS130X(&pTimer);
	}
	return 0;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
